/**
 * Labox有限公司项目InnovationServer
 * Labox版权所有 @copyright 2009
 * @javaclass LoginPackerHandler.java @author 丁宁 @time 2009-11-27
 */
package labox.innovation.loginserver.http;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import labox.innovation.config.Config;
import labox.innovation.loginserver.Client;
import labox.innovation.loginserver.HackingException;
import labox.innovation.loginserver.LoginController;
import labox.innovation.loginserver.SessionKey;
import labox.innovation.loginserver.GameServerTable.GameServerInfo;
import labox.innovation.loginserver.LoginController.AuthLoginResult;
import labox.innovation.loginserver.socket.LoginClient.LoginClientState;
import labox.innovation.loginserver.socket.serverpackets.LoginServerPacket;
import labox.innovation.loginserver.socket.serverpackets.ServerList;
import labox.innovation.util.Util;

import com.sun.net.httpserver.HttpExchange;

/**
 * @author Administrator
 * 
 */
public class LoginPackerHandler extends IPacketHandler {

	private static final Logger _log = LoggerFactory.getLogger(LoginPackerHandler.class.getName());

	@Override
	public boolean accept(InetSocketAddress address) {
		return true;
	}

	@Override
	public void run(HttpExchange t) {
		String path = t.getRequestURI().getPath();
		String query = t.getRequestURI().getQuery();

		if (path != null && path.equals("/login") && query != null) {
			String[] data = query.split("&");
			if (data != null && data.length == 2) {
				int ui = data[0].indexOf("u=");
				int pi = data[1].indexOf("p=");

				if (ui >= 0 && pi >= 0 && ui + 2 < data[0].length() && pi + 2 < data[1].length()) {
					String _user = data[0].substring(ui + 2);
					String _password = data[1].substring(pi + 2);

					LoginController lc = LoginController.getInstance();

					Httpclient client = new Httpclient(t.getRemoteAddress().getAddress());

					try {
						AuthLoginResult result = lc.tryAuthLogin(_user, _password, client);//去数据库查询账户密码是否正确

						switch (result) {
						case AUTH_SUCCESS:
							client.setAccount(_user);
							client.setState(LoginClientState.AUTHED_LOGIN);
							//							client.setSessionKey(client.getSessionId());
							t.sendResponseHeaders(200, 0);
							OutputStream os = t.getResponseBody();

							os.flush();
							os.close();
							break;
						case INVALID_PASSWORD:
						case ACCOUNT_BANNED:
						case ALREADY_ON_LS:
							if (lc.getAuthedClient(_user) != null) {
								// kick the other client
								lc.removeAuthedLoginClient(_user);
							}
							break;
						case ALREADY_ON_GS:
							GameServerInfo gsi;
							if ((gsi = lc.getAccountOnGameServer(_user)) != null) {
								// kick from there
								if (gsi.isAuthed()) {
									gsi.getGameServerThread().kickPlayer(_user);
								}
							}
							break;
						}
					} catch (HackingException e) {
						e.printStackTrace();
						InetAddress address = client.getInetAddress();
						lc.addBanForAddress(address, Config.LOGIN_BLOCK_AFTER_BAN * 1000);
						_log.info("Banned (" + address + ") for " + Config.LOGIN_BLOCK_AFTER_BAN + " seconds, due to " + e.getConnects() + " incorrect login attempts.", Config.SERVER_ID);
					} catch (IOException ex) {
						ex.printStackTrace();
					}
				}

			}
		}

	}

	static class Httpclient implements Client {

		private String _account;

		//		private SessionKey _sessionKey;

		private int _sessionKey;

		private LoginClientState _state;

		private int _accessLevel;

		private InetAddress _address;

		private int _lastServer;

		private long _connectionStartTime;

		private boolean _usesInternalIP;

		public Httpclient(InetAddress address) {
			_address = address;
			_connectionStartTime = System.currentTimeMillis();
			String ip = address.getHostAddress();

			if (Util.isInternalIP(ip) && !Config.ROUTER_HOSTNAME.equalsIgnoreCase(ip)) {
				_usesInternalIP = true;
			}
		}

		public void setAccount(String accout) {
			_account = accout;
		}

		public void setSessionKey(int sessionKey) {
			_sessionKey = sessionKey;
		}

		public void setState(LoginClientState state) {
			_state = state;
		}

		public String getAccount() {
			return _account;
		}

		public int getSessionKey() {
			return _sessionKey;
		}

		public LoginClientState getState() {
			return _state;
		}

		public int getAccessLevel() {
			return _accessLevel;
		}

		public void setAccessLevel(int accessLevel) {
			_accessLevel = accessLevel;
		}

		public InetAddress getInetAddress() {
			return _address;
		}

		public int getLastServer() {
			return _lastServer;
		}

		public void setLastServer(int lastServer) {
			_lastServer = lastServer;
		}

		public long getConnectionStartTime() {
			return _connectionStartTime;
		}

		public boolean usesInternalIP() {
			return _usesInternalIP;
		}

	}

}
